package offer

import (
	// "bp/cache"
	sqlc "bp/db/sqlc"
	"bp/internal/service/entity/coupon"
	// memberCoupon "bp/internal/service/entity/member_coupon"
	offTrial "bp/internal/service/entity/off_trial"
	"bp/internal/service/entity/promotion"
	"bp/internal/service/param"
	"bp/internal/util"
	"context"
)

// ListOfferPtrsOfOwnerParam 列出所有者可用的优惠项目参数
type ListOfferPtrsOfOwnerParam struct {
	OwnerID int64
	Issuer  string
}

// ListOfferPtrsOfItemID 列出商品可用的优惠项目
func (s *OfferComServiceImp) ListOfferPtrsOfOwner(ctx context.Context, q *sqlc.Queries, cPtr *param.ListCommonParam, ptr *ListOfferPtrsOfOwnerParam) (offerPtrs []*Offer, err error) {
	slog := util.NewContextLogger(ctx, s.slog)

	couponPtrs, err := s.entityHub.CouponService.ListCouponPtrsAsOfferOfOwner(ctx, q, cPtr, &coupon.ListCouponPtrsAsOfferOfItemIDParam{
		OwnerID: ptr.OwnerID,
		Issuer:  ptr.Issuer,
	})
	if err != nil {
		return
	}
	slog.Infof("1 ListCouponPtrsAsOfferOfOwner ok")
	couponOfferPtrs := s.MapCouponPtrsToOfferPtrs(couponPtrs, s.ConvCouponPtrToOfferPtr())
	offerPtrs = append(offerPtrs, couponOfferPtrs...)

	promotionPtrs, err := s.entityHub.PromotionService.ListPromotionPtrsAsOfferOfOwner(ctx, q, cPtr, &promotion.ListPromotionPtrsAsOfferOfItemIDParam{
		OwnerID: ptr.OwnerID,
		Issuer:  ptr.Issuer,
	})
	if err != nil {
		return
	}
	slog.Infof("2 ListCouponPtrsAsOfferOfOwner ok")
	promotionOfferPtrs := s.MapPromotionPtrsToOfferPtrs(promotionPtrs, s.ConvPromotionPtrToOfferPtr())
	offerPtrs = append(offerPtrs, promotionOfferPtrs...)

	return
}

// ListOfferPtrsOfItemIDParam 列出商品可用的优惠项目参数
type ListOfferPtrsOfItemIDParam struct {
	OwnerID int64
	Issuer  string
	ItemID  int64
}

// ListOfferPtrsOfItemID 列出商品可用的优惠项目
func (s *OfferComServiceImp) ListOfferPtrsOfItemID(ctx context.Context, q *sqlc.Queries, cPtr *param.ListCommonParam, ptr *ListOfferPtrsOfItemIDParam) (offerPtrs []*Offer, err error) {
	slog := util.NewContextLogger(ctx, s.slog)

	couponPtrs, err := s.entityHub.CouponService.ListCouponPtrsAsOfferOfItemID(ctx, q, cPtr, &coupon.ListCouponPtrsAsOfferOfItemIDParam{
		OwnerID: ptr.OwnerID,
		Issuer:  ptr.Issuer,
		ItemID:  ptr.ItemID,
	})
	if err != nil {
		return
	}
	slog.Infof("1 ListCouponPtrsAsOfferOfItemID ok")
	couponOfferPtrs := s.MapCouponPtrsToOfferPtrs(couponPtrs, s.ConvCouponPtrToOfferPtr())
	offerPtrs = append(offerPtrs, couponOfferPtrs...)

	promotionPtrs, err := s.entityHub.PromotionService.ListPromotionPtrsAsOfferOfItemID(ctx, q, cPtr, &promotion.ListPromotionPtrsAsOfferOfItemIDParam{
		OwnerID: ptr.OwnerID,
		Issuer:  ptr.Issuer,
		ItemID:  ptr.ItemID,
	})
	if err != nil {
		return
	}
	slog.Infof("2 ListPromotionPtrsAsOfferOfItemID ok")
	promotionOfferPtrs := s.MapPromotionPtrsToOfferPtrs(promotionPtrs, s.ConvPromotionPtrToOfferPtr())
	offerPtrs = append(offerPtrs, promotionOfferPtrs...)

	return
}

type GetTrialInfoParam struct {
	OutTransNo string
	TrialScene string
}

// DoTrial 试算优惠
func (s *OfferComServiceImp) GetTrialInfo(ctx context.Context, q *sqlc.Queries, ptr *GetTrialInfoParam) (
	off int32,
	trialedOwnerPtrs []*TrialedOwner,
	trialedOfferItemPtrOfCardDiscount *TrialedOfferItem,
	err error) {
	ownerIDToTrialedOwnerPtrMap := make(map[int64]*TrialedOwner)

	offTrialPtrs, err := s.entityHub.OffTrialService.ListOffTrialPtrs(ctx, q, &offTrial.ListOffTrialPtrsParam{
		OutTransNo: ptr.OutTransNo,
		TrialScene: ptr.TrialScene,
	})
	if err != nil {
		return
	}

	cardDiscountOffTrialPtrs, nonCardDiscountOffTrialPtrs := s.entityHub.OffTrialService.SplitOffTrialPtrs(offTrialPtrs, func(ot *sqlc.OffTrial) bool {
		return ot.OfferItemType == string(sqlc.EmOfferItemTypeCard) && ot.OfferType == string(sqlc.EmOfferTypeDiscount)
	})

	offTrialItemPtrs, err := s.entityHub.OffTrialService.ListOffTrialItemPtrs(ctx, q, &offTrial.ListOffTrialItemPtrsParam{
		OutTransNo: ptr.OutTransNo,
		TrialScene: ptr.TrialScene,
	})
	if err != nil {
		return
	}

	for _, offTrialPtr := range nonCardDiscountOffTrialPtrs {
		ownerID := offTrialPtr.OwnerID
		offTrialItemPtrsOfTheOffTrial := s.entityHub.OffTrialService.FilterOffTrialItemPtrs(offTrialItemPtrs, func(oti *sqlc.OffTrialItem) bool {
			return oti.OffTrialID == offTrialPtr.ID
		})
		if trialedOwnerPtr, ok := ownerIDToTrialedOwnerPtrMap[ownerID]; !ok {
			ownerIDToTrialedOwnerPtrMap[ownerID] = &TrialedOwner{
				OwnerID: ownerID,
				Off: offTrialPtr.Off,
				TrialedOffItemPtrs: []*TrialedOfferItem{
					s.ConvOffTrialPtrToTrialedOfferItemPtr(offTrialItemPtrsOfTheOffTrial)(offTrialPtr),
				},
			}
		} else {
			trialedOwnerPtr.Off += offTrialPtr.Off
			trialedOwnerPtr.TrialedOffItemPtrs = append(trialedOwnerPtr.TrialedOffItemPtrs,
				s.ConvOffTrialPtrToTrialedOfferItemPtr(offTrialItemPtrsOfTheOffTrial)(offTrialPtr),
			)
		}
	}

	for ownerID := range ownerIDToTrialedOwnerPtrMap {
		trialedOwner := ownerIDToTrialedOwnerPtrMap[ownerID]
		trialedOwnerPtrs = append(trialedOwnerPtrs, trialedOwner)
		off += trialedOwner.Off
	}

	for _, offTrialPtr := range cardDiscountOffTrialPtrs {
		if trialedOfferItemPtrOfCardDiscount == nil {
			offTrialItemPtrsOfTheOffTrial := s.entityHub.OffTrialService.FilterOffTrialItemPtrs(offTrialItemPtrs, func(oti *sqlc.OffTrialItem) bool {
				return oti.OffTrialID == offTrialPtr.ID
			})
			trialedOfferItemPtrOfCardDiscount = s.ConvOffTrialPtrToTrialedOfferItemPtr(offTrialItemPtrsOfTheOffTrial)(offTrialPtr)
		} else {
			trialedOfferItemPtrOfCardDiscount.Off += offTrialPtr.Off
		}
		off += offTrialPtr.Off
	}

	return
}

// // ListAvailablePromotionOfferPtrsForTrialParam 列出可用的促销活动优惠项用于试算的参数
// type ListAvailablePromotionOfferPtrsForTrialParam struct {
// 	BrandID     int64
// 	OwnerID     int64
// 	TrialIssuer string
// 	TrialScene  string
// }

// // ListAvailablePromotionOfferPtrsForTrial 列出可用的促销活动优惠项用于试算
// func (s *OfferComServiceImp) ListAvailablePromotionOfferPtrsForTrial(ctx context.Context, q *sqlc.Queries, ptr *ListAvailablePromotionOfferPtrsForTrialParam) (offerPtrs []*Offer, err error) {
// 	slog := util.NewContextLogger(ctx, s.slog)

// 	promotionPtrs, err := s.entityHub.PromotionService.ListAvailablePromotionsForDoTrial(ctx, q, &promotion.ListAvailablePromotionsForDoTrialParam{
// 		BrandID:  ptr.BrandID,
// 		OwnerID:  ptr.OwnerID,
// 		Issuer:   ptr.TrialIssuer,
// 		UseScene: ptr.TrialScene,
// 	})
// 	if err != nil {
// 		return
// 	}
// 	slog.Infof("1 ListAvailablePromotionsByForDoTrial ok")
// 	promotionOfferPtrs := s.MapPromotionPtrsToOfferPtrs(promotionPtrs, s.ConvPromotionPtrToOfferPtr())
// 	offerPtrs = append(offerPtrs, promotionOfferPtrs...)

// 	return
// }

// // ListAvailableMemberCouponOfferPtrsForTrialParam 列出可用的会员优惠券优惠项用于试算的参数
// type ListAvailableMemberCouponOfferPtrsBySnsForTrialParam struct {
// 	MemberID int64
// 	BrandID  int64
// 	OwnerID  int64
// 	Sns      []string
// }

// // ListAvailablePromotionOfferPtrsForTrial 列出可用的促销活动优惠项用于试算
// func (s *OfferComServiceImp) ListAvailableMemberCouponOfferPtrsBySnsForTrial(ctx context.Context, q *sqlc.Queries, ptr *ListAvailableMemberCouponOfferPtrsBySnsForTrialParam) (offerPtrs []*Offer, err error) {
// 	slog := util.NewContextLogger(ctx, s.slog)

// 	memberCouponPtrs, err := s.entityHub.MemberCouponService.ListAvailableMemberCouponsBySnsForDoTrial(ctx, q, &memberCoupon.ListAvailableMemberCouponsBySnsForDoTrialParam{
// 		MemberID: ptr.MemberID,
// 		BrandID:  ptr.BrandID,
// 		OwnerID:  ptr.OwnerID,
// 		Sns:      ptr.Sns,
// 	})
// 	if err != nil {
// 		return
// 	}
// 	slog.Infof("1 ListAvailableMemberCouponOfferPtrsBySnsForTrial ok")
// 	memberCouponOfferPtrs := s.MapMemberCouponPtrsToOfferPtrs(memberCouponPtrs, s.ConvMemberCouponPtrToOfferPtr())
// 	offerPtrs = append(offerPtrs, memberCouponOfferPtrs...)

// 	return
// }

// // ListAvailableMemberCouponOfferPtrsForTrialParam 列出可用的会员优惠券优惠项用于试算的参数
// type ListAvailableMemberCouponOfferPtrsForTrialParam struct {
// 	MemberID   int64
// 	BrandID    int64
// 	OwnerID    int64
// 	TrialScene string
// }

// // ListAvailablePromotionOfferPtrsForTrial 列出可用的促销活动优惠项用于试算
// func (s *OfferComServiceImp) ListAvailableMemberCouponOfferPtrsForTrial(ctx context.Context, q *sqlc.Queries, ptr *ListAvailableMemberCouponOfferPtrsForTrialParam) (offerPtrs []*Offer, err error) {
// 	slog := util.NewContextLogger(ctx, s.slog)

// 	memberCouponPtrs, err := s.entityHub.MemberCouponService.ListAvailableMemberCouponsByForDoTrial(ctx, q, &memberCoupon.ListAvailableMemberCouponsByForDoTrialParam{
// 		MemberID: ptr.MemberID,
// 		BrandID:  ptr.BrandID,
// 		OwnerID:  ptr.OwnerID,
// 		UseScene: ptr.TrialScene,
// 	})
// 	if err != nil {
// 		return
// 	}
// 	slog.Infof("1 ListAvailableMemberCouponOfferPtrsForTrial ok")
// 	memberCouponOfferPtrs := s.MapMemberCouponPtrsToOfferPtrs(memberCouponPtrs, s.ConvMemberCouponPtrToOfferPtr())
// 	offerPtrs = append(offerPtrs, memberCouponOfferPtrs...)

// 	return
// }
